<?php
/**
 * 应用公共文件
 *
 * Author : Traveler.
 * Time   : 2021/8/31 15:06
 */

use app\ErrorCode;
use Firebase\JWT\JWT;
use sunshine\exceptions\ApiException;

/**
 * 超级sign(调试使用)
 * md5('zhengzhi')
 */
const API_SUPER_SIGN = '9736b8641cebf22244cc1568cb1c8dc4';

/**
 * Token密钥
 */
const API_TOKEN_SECRET = '%@t41kE!svx$5^0x';

/**
 * 生成签名
 *
 * @param array $param 请求参数
 * @return string
 */
function generate_signature(array $param): string
{
    $salt_prefix = '0471';
    $salt_suffix = 'zhengzhi';

    ksort($param);
    $query_string = http_build_query($param);

    return $query_string ? md5($salt_prefix . md5($query_string . $salt_suffix)) : '';
}

/**
 * 验证签名
 *
 * @param array       $param 请求参数
 * @param string|null $sign  请求签名
 * @return bool
 */
function verify_signature(array $param, ?string $sign = null): bool
{
    return API_SUPER_SIGN === $sign || generate_signature($param) === $sign;
}

/**
 * 生成token
 *
 * @param array $data token载荷信息
 * @return string
 */
function generate_token(array $data): string
{
    $time   = time();
    $expire = $time + 72000;

    $payload = [
        'nbf' => $time,   //生效时间(官方字段)
        'iat' => $time,   //签发时间(官方字段)
        'exp' => $expire, //过期时间(官方字段)
    ];

    $payload = array_merge($payload, $data);

    return JWT::encode($payload, API_TOKEN_SECRET);
}

/**
 * 验证token
 *
 * @param string $authorization token字符串
 * @return mixed
 */
function verify_token(string $authorization)
{
    $authorization = trim($authorization);

    if (!preg_match('/^Bearer\s(\S+)/', $authorization, $matches)) {
        throw new ApiException(ErrorCode::INVALID_TOKEN, 401);
    }

    $algorithms = ['HS256'];

    try {
        $payload = json_decode(json_encode(JWT::decode($matches[1], API_TOKEN_SECRET, $algorithms)), true);
    } catch (DomainException | InvalidArgumentException | UnexpectedValueException $e) {
        throw new ApiException(ErrorCode::INVALID_TOKEN, 401);
    }

    if (!$payload) {
        throw new ApiException(ErrorCode::INVALID_TOKEN, 401);
    }

    return $payload;
}

/**
 * 加密密码
 *
 * @param string $password
 * @return string
 */
function encrypt_password(string $password): string
{
    return $password ? md5($password) : '';
}

/**
 * 生成Tree结构数据
 *
 * @param array  $dataList      数据数组
 * @param string $parentField   父级ID的字段名
 * @param string $childrenField 子级名称
 * @return array
 */
function list_to_tree(array $dataList, string $parentField = 'parent_id', string $childrenField = 'children'): array
{
    $temp = [];
    $tree = [];

    foreach ($dataList as $data) {
        $temp[$data['id']] = $data;
    }

    foreach ($temp as $k => $item) {
        $parent_id = $item[$parentField];
//        $temp[$k][$childrenField] = [];
        if (isset($temp[$parent_id])) {
            $temp[$parent_id][$childrenField][] = &$temp[$k];
        } else {
            $tree[] = &$temp[$k];
        }
    }

    return $tree;
}

/**
 * base64转url
 *
 * @param $text
 * @return string
 */
function base64_to_url($text): string
{
    $result = base64_encode($text);
    return str_replace(['+', '/', '='], ['-', '_', ''], $result);
}

/**
 * url转base64
 *
 * @param $text
 * @return bool|string
 */
function url_to_base64($text)
{
    $result = str_replace(['-', '_'], ['+', '/'], $text);
    $mod    = strlen($result) % 4;
    if ($mod) $result .= substr('====', $mod);

    return base64_decode($result);
}
